package testes;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import util.HibernateUtilTest;
import entidades.Produto;

public class ProdutoTest {

	private static Session sessao;
    private static Transaction transacao;

    @BeforeClass
    public  static void abreConexao() {
    	sessao = HibernateUtilTest.getSession().getCurrentSession();
    	transacao = sessao.beginTransaction();
    }

    @AfterClass
    public static void fechaConexao() {
		 try {
			 transacao.commit();
		 } catch (Throwable e) {
			 System.out.println("deu problema no commit : " + e.getMessage());
		 } finally {
			 try {
				 if (sessao.isOpen()) {
					 sessao.close();
				 }
			 } catch (Exception e2) {
				 System.out.println("Deu erro no fechamanto da sesso"+ e2.getMessage());
			 }
		 }
    }

    /*
     * todo teste chama o @before e @after uma vez, 
     * ou seja salva e deleta os dados na base
     */
    
    @Before
    public void setup(){
        Produto p1 = new Produto("Mouse", "10", new Date(), 60, 7.0f);
        Produto p2 = new Produto("Teclado", "20", new Date(), 70, 2.5f);
        Produto p3 = new Produto("Monitor", "30", new Date(), 80, 1.5f);
        Produto p4 = new Produto("Caixa de som", "40", new Date(), 90, 30.0f);
        Produto p5 = new Produto("Modem", "50", new Date(), 100, 1.5f);

        sessao.save(p1);
        sessao.save(p2);
        sessao.save(p3);
        sessao.save(p4);
        sessao.save(p5);
    }

    @After
    public void limpaBanco(){
        Criteria lista = sessao.createCriteria(Produto.class);
        @SuppressWarnings("unchecked")
        List<Produto> produtos = lista.list();

        for (Produto produto : produtos) {
        	sessao.delete(produto);
        }
    }

    @Test
    public void salvarProdutoTest() {
        Query consulta = pesquisar("Mouse");
        Produto produtoPesquisado = (Produto) consulta.uniqueResult();

        assertEquals("10", produtoPesquisado.getUnidade());
    }
   
    @Test
    public void listaProdutosTest(){
        Criteria lista = sessao.createCriteria(Produto.class);
        @SuppressWarnings("unchecked")
        List<Produto> produtos = lista.list();

        assertEquals(5, produtos.size());
    }
   
    @Test
    public void excluirProdutoTest(){
		Query consulta = pesquisar("Modem");
		Produto produtoDeletado = (Produto) consulta.uniqueResult();
		sessao.delete(produtoDeletado);
		
		produtoDeletado = (Produto) consulta.uniqueResult();
		
		assertNull(produtoDeletado);
    }

    @Test
    public void alteracaoProdutoTest(){
		Query consulta = pesquisar("Teclado");
		Produto produtoAlterado = (Produto) consulta.uniqueResult();
		produtoAlterado.setEstoque(100);
		
		sessao.update(produtoAlterado);
		
		produtoAlterado = (Produto) consulta.uniqueResult();
		
		assertEquals(100, produtoAlterado.getEstoque().intValue());
    }

    private Query pesquisar(String produto) {
		String sql = "from Produto p where p.descricao like :descricao";
		Query consulta = sessao.createQuery(sql);
		consulta.setString("descricao", "%"+produto+"%");
		return consulta;
    }
}
